package com.ble.demo.ui;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.ble.api.DataUtil;
import com.ble.demo.R;
import com.ble.demo.adapter.BleCmdAdapter;
import com.ble.demo.util.LeProxy;
import com.ble.utils.TimeUtil;
import com.ble.utils.ToastUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * 大数据传输，即突破一次只能发送20字节的限制，须手机系统不低于Android5.0
 * Created by Administrator on 2017/8/10 0010.
 */

public class MtuFragment extends Fragment implements View.OnClickListener {
    private static final String TAG = "MtuFragment";

    private LeProxy mLeProxy;
    private Spinner mSpinnerDevice;
    private EditText mEdtTxData;
    private final List<String> mRxDataList = new ArrayList<>();
    private RecyclerView mRvRxData;
    private RxDataAdapter mRxAdapter;
    private TextView mBtnClearRx;

    private String mSelectedAddress;
    private ArrayAdapter<String> mDeviceAdapter;

    private int mMtu = 251;

    private final List<String> mBleCmdList = new ArrayList<>();

    private void initBleCmdData() {
        mBleCmdList.clear();
        mBleCmdList.add("#AUTOCHECK,YTWF001,N01");
        mBleCmdList.add("#PRINTIDENTY,YTWF001,N01");
        mBleCmdList.add("#STLAT,YTWF001,N01");
        mBleCmdList.add("#STLON,YTWF001,N01");
        mBleCmdList.add("#PRINTPARAM,YTWF001,N01");
        mBleCmdList.add("#STALTP,YTWF001,N01");
        mBleCmdList.add("#STALT,YTWF001,N01");
        mBleCmdList.add("#PRINTVER,YTWF001,N01");
        mBleCmdList.add("#STEM,YTWF001,N01");
        mBleCmdList.add("#STCI,YTWF001,N01");
        mBleCmdList.add("#LS,YTWF001,N01");
        mBleCmdList.add("#PRINTST,YTWF001,N01");
        mBleCmdList.add("#PRINTOB,YTWF001,N01");
        mBleCmdList.add("#PRINTME,YTWF001,N01");
        mBleCmdList.add("#NID,YTWF001,Nnn");
        mBleCmdList.add("#NID,YTWF001,N01,N02");
        mBleCmdList.add("#DATETIME,YTWF001,N01");
        mBleCmdList.add("#PRINTSN,YTWF001,N01");
        mBleCmdList.add("#STNID,YTWF001,N01");
        mBleCmdList.add("#RESET,YTWF001,N01");
        mBleCmdList.add("#STEH,YTWF001,N01,2");
        mBleCmdList.add("#INTERVAL,YTWF001,N01,ST");
        mBleCmdList.add("#INTERVAL,YTWF001,N01,OB");
        mBleCmdList.add("#OBFORMAT,YTWF001,N01");
        mBleCmdList.add("#PRINTSAMPLE,YTWF001,N01");
    }
    private final BroadcastReceiver mGattReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String address = intent.getStringExtra(LeProxy.EXTRA_ADDRESS);
            if (LeProxy.ACTION_DATA_AVAILABLE.equals(intent.getAction())) {
                assert address != null;
                if (address.equals(mSelectedAddress)) {
                    displayRxData(intent);
                }
            } else if (LeProxy.ACTION_MTU_CHANGED.equals(intent.getAction())) {
                int status = intent.getIntExtra(LeProxy.EXTRA_STATUS, BluetoothGatt.GATT_FAILURE);
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    mMtu = intent.getIntExtra(LeProxy.EXTRA_MTU, 251);
                    ToastUtil.show(getActivity(), "MTU has been " + mMtu);
                } else {
                    ToastUtil.show(getActivity(), "MTU update error: " + status);
                }
            }
        }
    };


    private void displayRxData(Intent intent) {
//        String uuid = intent.getStringExtra(LeProxy.EXTRA_UUID);
        byte[] data = intent.getByteArrayExtra(LeProxy.EXTRA_DATA);
//        String dataStr = "timestamp: " +  + '\n'
//                + "uuid: " + uuid + '\n'
//                + "length: " + (data == null ? 0 : data.length) + '\n';
        String dataStr = "<" + TimeUtil.timestamp("HH:mm:ss") + ">" ;
//        if (mDataType == 0) {
//            dataStr += "数据: " + DataUtil.byteArrayToHex(data);
//        } else {
            if (data == null) {
                dataStr += "收到:";
            } else {
                dataStr += "收到: " + new String(data);
            }
//        }
//        mTxtRxData.setText(dataStr);
        mRxDataList.add(dataStr);
        mRxAdapter.notifyItemInserted(mRxDataList.size() - 1);
        mRvRxData.scrollToPosition(mRxDataList.size() - 1);
    }

    private IntentFilter makeFilter() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(LeProxy.ACTION_MTU_CHANGED);
        filter.addAction(LeProxy.ACTION_DATA_AVAILABLE);
        return filter;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); // 初始化数据
        mLeProxy = LeProxy.getInstance();
        mLeProxy.requestMtu(mSelectedAddress, 251);
        LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mGattReceiver, makeFilter());
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_mtu, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mSpinnerDevice = view.findViewById(R.id.spinner_device);
        updateConnectedDevices();
        // 初始化10条指令数据
        initBleCmdData();
//        ArrayAdapter<String> dataTypeAdapter = new ArrayAdapter<String>(getActivity(),
//                android.R.layout.simple_spinner_item, new String[]{"hex", "ascii"});
        mLeProxy.requestMtu(mSelectedAddress, 251);
        mRvRxData = view.findViewById(R.id.rv_rx_data);
        // 线性布局（垂直排列历史数据）
        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
        mRvRxData.setLayoutManager(layoutManager);
        mRxAdapter = new RxDataAdapter(mRxDataList);
        mRvRxData.setAdapter(mRxAdapter);

        mBtnClearRx = view.findViewById(R.id.btn_clear_rx);
        mBtnClearRx.setOnClickListener(this); // 绑定点击事件

        mEdtTxData = view.findViewById(R.id.edt_tx_data);
//        mEdtMtu = (EditText) view.findViewById(R.id.edt_mtu);
        view.findViewById(R.id.btn_send).setOnClickListener(this);
//        view.findViewById(R.id.btn_update_mtu).setOnClickListener(this);
        view.findViewById(R.id.main_btn_show_list).setOnClickListener(this);
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.i(TAG, "onResume()");
//        mLeProxy.setEncrypt(mBoxEncrypt.isChecked());
        mLeProxy.setEncrypt(false);
    }

//    private void updateTxData() {
//        StringBuilder sb = new StringBuilder();
//        int max = mBoxEncrypt.isChecked() ? mMtu - 6 : mMtu - 3;//加密要用去3字节
//
//        if (mDataType == 0) {//hex
//            for (int i = 0; i < max; i++) {
//                sb.append(String.format("%02X", i));
//            }
//        } else {//ascii
//            for (int i = 0; i < max; i++) {
//                sb.append((char) (i % 26 + 'A'));
//            }
//        }
//        mEdtTxData.setText(sb.toString());
//    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mGattReceiver);
    }

    @SuppressLint({"NonConstantResourceId", "NotifyDataSetChanged"})
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_send:
                send();
                break;
//            case R.id.btn_update_mtu:
//                updateMtu();
//                break;
            case R.id.main_btn_show_list:
                showCmdListDialog();
                break;
//            case R.id.box_hex:
//                if (mDataType == 0) {
//                    mDataType = 1;
//                } else {
//                    mDataType = 0;
//                }
//                updateTxData();
//                break;
            // 新增：清空接收历史
            case R.id.btn_clear_rx:
                if (!mRxDataList.isEmpty()) {
                    mRxDataList.clear(); // 清空历史数据列表
                    mRxAdapter.notifyDataSetChanged(); // 刷新列表（全量刷新，数据清空时可用）
                    ToastUtil.show(getContext(), "接收历史已清空");
                } else {
                    ToastUtil.show(getContext(), "接收历史为空");
                }
                break;
        }
    }

    // 弹框显示10条BLE指令（支持滚动）
    private void showCmdListDialog() {
        Context context = getContext();
        if (context == null) return;
        View dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_ble_cmd_list, null);
        RecyclerView rvCmd = dialogView.findViewById(R.id.rv_cmd_list);
        // 2. 初始化RecyclerView（线性布局+滚动支持）
        rvCmd.setLayoutManager(new LinearLayoutManager(context)); // 垂直列表
        rvCmd.setHasFixedSize(true); // 固定大小，提升滚动性能
        AlertDialog bleCmdDialog = new AlertDialog.Builder(context)
                .setView(dialogView)
                .setNegativeButton("关闭", (dialog, which) -> dialog.dismiss()) // 保留手动关闭按钮
                .setCancelable(true)
                .create();
        BleCmdAdapter adapter = new BleCmdAdapter(mBleCmdList, selectedCmd -> {
            if (mEdtTxData != null) {
                mEdtTxData.setText(selectedCmd);
                mEdtTxData.setSelection(selectedCmd.length()); // 光标定位到末尾
            }
            if (bleCmdDialog.isShowing()) { // 确保弹窗正在显示，避免重复调用
                bleCmdDialog.dismiss();
            }
        });
        rvCmd.setAdapter(adapter);
        bleCmdDialog.show();
    }

//    private void updateMtu() {
//        String mtuStr = mEdtMtu.getText().toString();
//        if (!mtuStr.isEmpty()) {
//            int mtu = Integer.parseInt(mtuStr);
//            Log.i(TAG, "updateMtu() - " + mSelectedAddress + ", mtu=" + mtu);
//            mLeProxy.requestMtu(mSelectedAddress, mtu);
//        }
//    }

    private void send() {
        try {
            String txData = mEdtTxData.getText().toString();
            if (!txData.isEmpty()) {
//                byte[] data;
//                if (mDataType == 0) {//hex
//                    data = DataUtil.hexToByteArray(txData);
//                } else {//ascii
                txData= txData + "\r\n";
                byte[] data = txData.getBytes();
//                }
                mLeProxy.send(mSelectedAddress, data);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void updateConnectedDevices() {
        List<BluetoothDevice> deviceList = mLeProxy.getConnectedDevices();
        String[] deviceArr;
        if (!deviceList.isEmpty()) {
            deviceArr = new String[deviceList.size()];
            for (int i = 0; i < deviceArr.length; i++) {
                deviceArr[i] = deviceList.get(i).getAddress();
            }
        } else {
            deviceArr = new String[]{getString(R.string.mtu_no_device_connected)};
        }
        mDeviceAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_dropdown_item, deviceArr);
        mSpinnerDevice.setAdapter(mDeviceAdapter);
        mSpinnerDevice.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                mSelectedAddress = mDeviceAdapter.getItem(position);
                mLeProxy.requestMtu(mSelectedAddress, 251);
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
    }
    private static class RxDataAdapter extends RecyclerView.Adapter<RxDataAdapter.RxViewHolder> {
        private final List<String> mDataList;
        public RxDataAdapter(List<String> dataList) {
            this.mDataList = dataList;
        }
        static class RxViewHolder extends RecyclerView.ViewHolder {
            TextView tvRxItem;
            public RxViewHolder(View itemView) {
                super(itemView);
                tvRxItem = itemView.findViewById(R.id.tv_rx_item);
                itemView.setOnLongClickListener(v -> {
                    String content = tvRxItem.getText().toString().trim();
                    if (content.isEmpty()) {
                        Toast.makeText(itemView.getContext(), "无内容可复制", Toast.LENGTH_SHORT).show();
                        return true; // 消费长按事件，避免传递
                    }
                    copyToClipboard(itemView.getContext(), content);
                    Toast.makeText(itemView.getContext(), "报文内容已复制", Toast.LENGTH_SHORT).show();
                    return true; // 表示“已处理长按事件”，防止其他监听器干扰
                });
            }

            /**
             * 工具方法：将内容复制到系统剪贴板（兼容 Android 13+）
             * @param context 上下文（用列表项的 context，避免内存泄漏）
             * @param content 要复制的报文内容
             */
            private void copyToClipboard(Context context, String content) {
                ClipboardManager clipboardManager = context.getSystemService(ClipboardManager.class);
                if (clipboardManager == null) {
                    Toast.makeText(context, "复制失败，请重试", Toast.LENGTH_SHORT).show();
                    return;
                }
                ClipData clipData = ClipData.newPlainText("BLE 报文", content);
                clipboardManager.setPrimaryClip(clipData);
            }
        }

        @NonNull
        @Override
        public RxViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View itemView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_rx_data, parent, false);
            return new RxViewHolder(itemView);
        }

        @Override
        public void onBindViewHolder(@NonNull RxViewHolder holder, int position) {
            String rxItem = mDataList.get(position);
            holder.tvRxItem.setText(rxItem);
            holder.tvRxItem.setTextColor(Color.parseColor("#999999"));
        }

        @Override
        public int getItemCount() {
            return mDataList.size();
        }
    }
}